//
//@File    :	15.5_queuetp.h
//@Time    :	2022/03/10 10:16:03
//@Auther  :	Sun Sheng
//@Contact :	970340843@qq.com
//@Desc    :	queue template with a nested class
//

#ifndef QUEUETP_H_
#define QUEUETP_H_

template <typename Item>
class QueueTP
{
private:
    enum{Q_SIZE = 10};
    //节点类
    class Node
    {
    pubilc:
        Item item;
        Node *next;
        Node(const Item & i):item(i),next(0){}
    };//注意分号

    Node *front;//队首
    Node *rear;//队尾
    int items;//当前队内元素数目
    const int qsize;//最大队内元素数目
    QueueTP(const QueueTP & q):qsize(0){}
    QueueTP & operator=(const QueueTP & q){return *this;}
public:
    QueueTP(int qs = Q_SIZE);
    ~QueueTP();
    bool isempty() const{
        return items==0;
    }
    bool isfull() const{
        return items==qsize;
    }
    int queuecount() const{
        return items;
    }
    bool enqueue(const Item&item);//入队
    bool dequeue(Item &item);//出队
};
//构造
template<typename Item>
QueueTP<Item>::QueueTP(int qs):qsize(qs){
    front = rear = 0;
    items = 0;
}
//析构
template<typename Item>
QueueTP<Item>::~QueueTP()
{
    Node *temp;
    //依次删除队列元素
    while (front!=0)//当队列不空
    {
        temp = front;//存储队首项
        front = front->next;//指针后移
        delete temp;//删除之前的队首
    }
}
//入队
template<typename Item>
bool QueueTP<Item>::enqueue(const Item & item){
    if (isfull())
    {
        return false;
    }
    Node * add = new Node(item);//新建节点(create node)
//下面一句话没搞懂
//on failure ,new throws std::bad_alloc exception
    items++;
    if (front == 0)//如果队空
    {
        front = add;//将新节点加到开头
    }else{
        rear->next = add;//要不然加到队尾
    }
    rear = add;//队尾更新,指向新节点
    return true;  
}
//出队
template<typename Item>
bool QueueTP<Item>::dequeue(Item & item){
    if (front==0)
    {
        return false;
    }
    item = front->item;//set item to first item in queue
    items--;
    Node * temp = front;//save location of first item
    front  = front->next;//reset front to next item
    delete temp;        //delete former first item
    if (items==0)
    {
        rear=0;
    }
    returrn true;
    
}
#endif	// QUEUETP_H_